package com.ecommerce.dddmodules.shippingcontext.service;

import com.ecommerce.dddmodules.sharedkernel.events.ApplicationEvent;
import com.ecommerce.dddmodules.sharedkernel.events.EventBus;
import com.ecommerce.dddmodules.sharedkernel.events.EventSubscriber;
import com.ecommerce.dddmodules.shippingcontext.model.Parcel;
import com.ecommerce.dddmodules.shippingcontext.model.ShippableOrder;
import com.ecommerce.dddmodules.shippingcontext.repository.ShippingOrderRepository;

import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
/**
 * @packageName: shippingcontext.service（发货上下文.服务包）
 * @className: ParcelShippingService(包裹发货服务实现)
 * @description: 实现发货服务接口
 * @author: luds
 * @version: v1.0
 * @date: 2021-04/02
 */
public class ParcelShippingService implements ShippingService {
	/**
	 * 订单准备装运事件
	 */
	public static final String EVENT_ORDER_READY_FOR_SHIPMENT = "OrderReadyForShipmentEvent";

	/**
	 * 发货单存储库
	 */
	private ShippingOrderRepository orderRepository;

	/**
	 * 事件总线
	 */
	private EventBus eventBus;

	/**
	 * 已发货包裹对照表
	 */
	private Map<Integer, Parcel> shippedParcels = new HashMap<>();

	/**
	 * 根据订单ID进行发货（具体实现）
	 * @param orderId 订单ID
	 */
	@Override
	public void shipOrder(int orderId) {
		Optional<ShippableOrder> order = this.orderRepository.findShippableOrder(orderId);
		order.ifPresent(completedOrder -> {
			Parcel parcel = new Parcel(completedOrder.getOrderId(), completedOrder.getAddress(), completedOrder.getPackageItems());
			if (parcel.isTaxable()) {
				// Calculate additional taxes
			}
			// Ship parcel
			this.shippedParcels.put(completedOrder.getOrderId(), parcel);
		});
	}
	/**
	 * 监听订购事件（具体实现）
	 */
	@Override
	public void listenToOrderEvents() {
		//
		this.eventBus.subscribe(EVENT_ORDER_READY_FOR_SHIPMENT, new EventSubscriber() {
			@Override
			public <E extends ApplicationEvent> void onEvent(E event) {
				shipOrder(Integer.parseInt(event.getPayloadValue("order_id")));
			}
		});
	}
	/**
	 * 根据订单ID获取包裹信息（具体实现）
	 * @param orderId 订单ID
	 * @return 返回包裹信息
	 */
	@Override
	public Optional<Parcel> getParcelByOrderId(int orderId) {
		// 对应订单ID的包裹如果有，直接返回；否则返回空
		return Optional.ofNullable(this.shippedParcels.get(orderId));
	}
	/**
	 * 设置订单存储库（具体实现）
	 * @param orderRepository 订单存储库
	 */
	@Override
	public void setOrderRepository(ShippingOrderRepository orderRepository) {
		this.orderRepository = orderRepository;
	}
	/**
	 * 获取事件总线（具体指定）
	 * @return 返回事件总线
	 */
	@Override
	public EventBus getEventBus() {
		return eventBus;
	}
	/**
	 * 设置事件总线（具体指定）
	 * @param eventBus 事件总线
	 */
	@Override
	public void setEventBus(EventBus eventBus) {
		this.eventBus = eventBus;
	}


}
